package com.hailiang.saas.auth.filter;

import com.hailiang.mp.commonsource.api.CommonResult;
import com.hailiang.saas.auth.common.Constant;
import com.hailiang.saas.auth.config.AuthenticationConfig;
import com.hailiang.saas.auth.service.CommonService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author : pangfuzhong
 * @description
 * @date : 2021/9/27 13:55
 */
public class TokenAuthenticationFilter extends BasicAuthenticationFilter {
    private AuthenticationConfig authenticationConfig;

    public TokenAuthenticationFilter(AuthenticationConfig authenticationConfig, AuthenticationManager authenticationManager) {
        super(authenticationManager);
        this.authenticationConfig = authenticationConfig;
    }

    public TokenAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint, AuthenticationConfig authenticationConfig) {
        super(authenticationManager, authenticationEntryPoint);
        this.authenticationConfig = authenticationConfig;
    }

    /**
     * description: 从request的header部分读取Token
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 1、如果为登出url直接过滤, 走登出filter
        if(StringUtils.contains(request.getRequestURL().toString(), this.authenticationConfig.getLogoutAuthUrl())) {
            chain.doFilter(request, response);
            return;
        }

        // 2、获取token, 如果请求头中没有Authorization信息, 说明没有登陆, 调用认证中心返回当前服务名称对应的登陆地址(不同的web应用会有各自的登陆地址)
        String accessToken = this.getRequestAccessToken(request);
        if(StringUtils.isBlank(accessToken)) {
            chain.doFilter(request, response);
            return;
        }

        // 3、认证token
        CommonResult commonResult = new CommonResult();
        commonResult.setSuccess(Boolean.TRUE);
        CommonService.authenticateTokenValid(this.authenticationConfig, accessToken, commonResult);
        if(commonResult.isSuccess()) {
            commonResult.setObject(commonResult.getObject());
        }
        CommonService.returnResponse(response, commonResult);
    }

    private String getRequestAccessToken(HttpServletRequest request) {
        String tokenHeader = request.getHeader(Constant.TOKEN_HEADER);
        if (tokenHeader == null || !tokenHeader.startsWith(Constant.TOKEN_SPLIT)) {
            return "";
        }

        return tokenHeader.replace(Constant.TOKEN_SPLIT, "").trim();
    }
}
